package com.evaluationSystem.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONObject;
import com.evaluationSystem.config.PropertiesConfig;
import com.evaluationSystem.config.R;
import com.evaluationSystem.entity.Appraise;
import com.evaluationSystem.entity.SysUserEntity;
import com.evaluationSystem.entity.dto.AppraiseDto;
import com.evaluationSystem.entity.dto.Fraction;
import com.evaluationSystem.entity.dto.ScoreDto;
import com.evaluationSystem.entity.vo.AnalyseListVo;
import com.evaluationSystem.entity.vo.AnalyseOwnVo;
import com.evaluationSystem.entity.vo.AppraiseDetail;
import com.evaluationSystem.entity.vo.AppraiseVo;
import com.evaluationSystem.excel.AppraiseExcel;
import com.evaluationSystem.exception.EvaluationException;
import com.evaluationSystem.mapper.AppraiseMapper;
import com.evaluationSystem.mapper.FractionMapper;
import com.evaluationSystem.mapper.ScoreMapper;
import com.evaluationSystem.mapper.SysUserDao;
import com.evaluationSystem.service.AppraiseService;
import com.evaluationSystem.util.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@RequiredArgsConstructor
public class AppraiseImpl implements AppraiseService {

    private final AppraiseMapper appraiseMapper;
    private final ScoreMapper scoreMapper;
    private final FractionMapper fractionMapper;

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private PropertiesConfig propertiesConfig;
    @Autowired
    private SmsSend smsSend;
    @Autowired
    private ScoreImpl scoreImpl;

    @Transactional
    @Override
    public AnalyseOwnVo getEvaluateObject(Appraise appraise) {
        AnalyseOwnVo evaluateObject = appraiseMapper.getEvaluateObject(appraise);
        for (AnalyseOwnVo.AppraiserUser appraiserUser : evaluateObject.getAppraiserUser()) {
            //遍历评价列表找出列表内是否存在被评价用户姓名，存在则状态为已填写
            if (StringUtils.isNotBlank(appraiserUser.getUserScore())) {
                appraiserUser.setAppraiseStatus(1);
            } else {
                appraiserUser.setAppraiseStatus(0);
            }
        }
        List<AnalyseOwnVo.AppraiserUser> filteredAppraiserUsers = evaluateObject.getAppraiserUser().stream()
                .filter(user -> user.getAppraiseStatus() == 1)
                .collect(Collectors.toList());


        ScoreDto scoreDto = new ScoreDto();
        scoreDto.setQuestionId(appraise.getQuestionId());
        List<AnalyseListVo> analyseList = scoreImpl.getAnalyseLists(scoreDto,appraise.getQuestionId());
        for (AnalyseListVo analyseItem : analyseList) {
            for (AnalyseOwnVo.AppraiserUser appraiserUser : filteredAppraiserUsers) {
                if (analyseItem.getAssessedId().equals(appraiserUser.getAssessedId())) {
                    Fraction fraction = new Fraction();

                    fraction.setAssessedName(analyseItem.getAssessedName());
                    fraction.setAssessedId(analyseItem.getAssessedId());

                    fraction.setAppraiserId(appraise.getAppraiserPhone());
                    fraction.setAppraiserPhone(appraise.getAppraiserPhone());
                    fraction.setQuestionId(appraise.getQuestionId());
                    System.out.println("AssessedName："+fraction.getAssessedName());
                    System.out.println("AssessedId："+fraction.getAssessedId());
                    System.out.println("AppraiserId："+fraction.getAppraiserId());
                    System.out.println("AppraiserPhone："+fraction.getAppraiserPhone());
                    System.out.println("QuestionId："+fraction.getQuestionId());
                    String dj = fractionMapper.selectFenshuByCriteria(fraction.getAssessedName(),
                            fraction.getAssessedId(),
                            fraction.getAppraiserId(),
                            fraction.getAppraiserPhone(),
                            fraction.getQuestionId());

                    if (dj != null) {
                        appraiserUser.setFenshu(Double.valueOf(dj));
//                    } else {
//                    appraiserUser.setFenshu(analyseItem.getScoreTotal());
//                    System.out.println("得分为："+analyseItem.getScoreTotal());
//                    break;
                    }
                }
            }
        }
        return evaluateObject;
    }


    public List<Appraise> getAppraiseLists(Appraise appraise) {
        List<Appraise> appraises = appraiseMapper.getAppraiseList(appraise);
        return appraises;
    }

    private AppraiseVo convertToAppraiseVo(Appraise appraise) {
        AppraiseVo appraiseVo = new AppraiseVo();
        // 将 appraise 的属性赋值给 appraiseVo
        return appraiseVo;
    }
    public List<AppraiseVo> getAppraiseList(Appraise appraise) {
        List<AppraiseVo> resultList = new ArrayList<>();
        List<Appraise> appraises = appraiseMapper.getAppraiseList(appraise);
        Map<String, List<Appraise>> appraiseMapList = appraises.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(Appraise::getAppraiserId));
        appraiseMapList.forEach((k, v) -> {
            List<Appraise> appraiseTimeList = appraiseMapper.getScoreList(k, null, v.get(0).getQuestionId());
            AppraiseVo appraiseVo = new AppraiseVo();
            appraiseVo.setDeptId(v.get(0).getDeptId());
            appraiseVo.setDeptName(v.get(0).getDeptName());
            appraiseVo.setAppraiserId(v.get(0).getAppraiserId());
            appraiseVo.setAppraiserName(v.get(0).getAppraiserName());
            appraiseVo.setAppraiserPhone(v.get(0).getAppraiserPhone());
            appraiseVo.setAppraiseNotice(v.get(0).getAppraiseNotice());
            appraiseVo.setCompleteStatus(v.get(0).getCompleteStatus());
            appraiseVo.setQuestionId(v.get(0).getQuestionId());
            appraiseVo.setAppraiseCount(v.size());
            appraiseVo.setAppraisedCount(appraiseTimeList.size());
            appraiseVo.setUnAppraiseCount(v.size() - appraiseTimeList.size());
            StringBuilder builder = new StringBuilder();
            List<AppraiseVo.subList> subList = new ArrayList<>();
            for (Appraise vo : v) {
                AppraiseVo.subList sub = new AppraiseVo.subList();
                BeanUtils.copyProperties(vo, sub);
                subList.add(sub);
                builder.append(vo.getAssessedName()).append(",");
            }
            appraiseVo.setSubList(subList);
            if (appraiseVo.getAppraiseStatus() != null && appraiseVo.getAppraiseStatus().equals(1)) {
                appraiseVo.setAppraiseTime(appraiseTimeList.stream().sorted(Comparator.comparing(Appraise::getAppraiseTime).reversed()).map(Appraise::getAppraiseTime).collect(Collectors.toList()).get(0));
            }
            appraiseVo.setAssessedName(builder.deleteCharAt(builder.lastIndexOf(",")).toString());
            if (appraise.getAppraiseStatus() != null) {
                if (appraiseVo.getAppraiseStatus() != null && appraiseVo.getAppraiseStatus().equals(appraise.getAppraiseStatus())) {
                    resultList.add(appraiseVo);
                }
            } else {
                resultList.add(appraiseVo);
            }
        });
        return resultList;
    }

//    @Override
//    public PageData<Appraise> getAppraisePage(Appraise appraise) {
//        int index = appraise.getPage() == 0 ? 0 : appraise.getPage() - 1 ;
//        appraise.setPage(index * appraise.getLimit());
//        Integer count = appraiseMapper.getAppraiseCount(appraise.getQuestionId());
//        List<Appraise> resultList = getAppraiseLists(appraise);
//        return new PageData<>(resultList, count);
//    }

    @Override
    public PageData<AppraiseVo> getAppraisePage(Appraise appraise) {
        int index = appraise.getPage() == 0 ? 0 : appraise.getPage() - 1 ;
        appraise.setPage(index * appraise.getLimit());
        System.out.println(appraise);
        System.out.println(appraise.getAppraiseStatus());
        Integer count = appraiseMapper.getAppraiseCount(appraise.getQuestionId());
        List<AppraiseVo> resultList = getAppraiseList(appraise);
        return new PageData<>(resultList, count);
    }

    @Override
    public PageData<Appraise> selectAppraiseList(Appraise appraise)
    {
        return appraiseMapper.selectAppraiseList(appraise);
    }
    @Override
    public void exportAppraise(HttpServletResponse response, Map<String, Object> params) throws Exception {
        Appraise appraise = new Appraise();
        String key = (String) params.get("key");
        String assessedName = (String) params.get("assessedName");
        String completeStatusStr = (String) params.get("completeStatus");
        String appraiseNoticeStr = (String) params.get("appraiseNotice");
        String appraiseStatusStr = (String) params.get("appraiseStatus");


        Integer completeStatus = null;
        Integer appraiseNotice = null;
        Integer appraiseStatus = null;

        if (StringUtils.isNotBlank(completeStatusStr)) {
            completeStatus = Integer.valueOf(completeStatusStr);
        }
        if (StringUtils.isNotBlank(appraiseNoticeStr)) {
            appraiseNotice = Integer.valueOf(appraiseNoticeStr);
        }
        if (StringUtils.isNotBlank(appraiseStatusStr)) {
            appraiseStatus = Integer.valueOf(appraiseStatusStr);
        }
        appraise.setQueryKey(key);
        appraise.setQuestionId((String) params.get("questionId"));
        appraise.setAssessedName(assessedName);
        appraise.setCompleteStatus(completeStatus);
        appraise.setAppraiseNotice(appraiseNotice);
        appraise.setAppraiseStatus(appraiseStatus);

        // 导出不进行分页
        appraise.setPage(null);
        appraise.setLimit(null);

        List<AppraiseVo> appraiseList = getAppraiseList(appraise);

        ExcelUtils.exportExcelToTarget11(response, "导出关系列表.xlsx", appraiseList, AppraiseExcel.class);
    }

    @Override
    public HashMap<String, Object> uploadAppraise(MultipartFile multipartFile, String questionId) {
        CommonUtil.uploadExcel(multipartFile);
        ExcelListener listener = new ExcelListener();
        HashMap<String, Object> resultMap = new HashMap<>();
        try {
            //注：headRowNumber默认为1
            EasyExcel.read(multipartFile.getInputStream(), listener).sheet().doRead();
        } catch (Exception e) {
            log.error("EasyExcel解析文件失败", e);
            throw new EvaluationException("文件解析失败，请重新上传");
        }
        //数据行信息
        List<Map<Integer, Map<Integer, String>>> list = listener.getList();
        //表头信息
        Map<Integer, String> headTitleMap = listener.getHeadTitleMap();
        //获取动态表头信息
        List<String> headList = headTitleMap.keySet().stream().map(key -> {
            String head = headTitleMap.get(key);
            log.info(head);
            return head;
        }).collect(Collectors.toList());//可以对表头进行入库保存，方便后续导出
        List<Integer> requiredList = new ArrayList<>();//必填字段的索引值
        headTitleMap.forEach((k, v) -> {
            if (v.contains("(必填)")) {
                requiredList.add(k);
            }
        });


        int successCount = 0;
        List<Object> resultList = new ArrayList<>();
        resultList.add(headList);
        for (int i = 0; i < list.size(); i++) {
            SysUserEntity byMobile = null;
            SysUserEntity byRealName = null;
            Integer appraiseTiesId = null;

            list.get(i).get(i + 1).put(list.get(i).get(i + 1).size(), "0");//0、成功 1、必填字段缺失 2、手机号格式错误 3、手机号不存在 4、被评估人不存在 5、评估人与被评估人关系错误
            for (int j = 0; j < list.get(i).get(i + 1).size(); j++) {
                if (requiredList.contains(j)) {
                    String col = list.get(i).get(i + 1).get(j);
                    //判断必填逻辑
                    if (col == null) {
                        list.get(i).get(i + 1).put(list.get(i).get(i + 1).size() - 1, "1");
                        break;
                    } else {    // 判断手机号的列
                        if (j == 3) {
                            // 校验手机号逻辑
                            if (!CommonUtil.isMobileNO(col)) {
                                list.get(i).get(i + 1).put(list.get(i).get(i + 1).size() - 1, "2");
                                break;
                            } else {
                                byMobile = sysUserDao.getByMobile(col);
                                if (byMobile == null) {
                                    list.get(i).get(i + 1).put(list.get(i).get(i + 1).size() - 1, "3");
                                    break;
                                }
                            }
                        } else if (j == 4) {    // 判断被评估人的列
                            byRealName = sysUserDao.getByRealName(col);
                            if (byRealName == null) {
                                list.get(i).get(i + 1).put(list.get(i).get(i + 1).size() - 1, "4");
                                break;
                            }
                        } else if (j == 6) {    // 评估人与被评估人关系的列
                            switch (col) {
                                case "权重1":
                                    appraiseTiesId = 1;
                                    break;
                                case "权重2":
                                    appraiseTiesId = 2;
                                    break;
                                case "权重3":
                                    appraiseTiesId = 3;
                                    break;
                                case "权重4":
                                    appraiseTiesId = 4;
                                    break;
                                case "权重5":
                                    appraiseTiesId = 5;
                                    break;
                                case "权重6":
                                    appraiseTiesId = 6;
                                    break;
                                case "权重7":
                                    appraiseTiesId = 7;
                                    break;
                                case "权重8":
                                    appraiseTiesId = 8;
                                    break;
                                default:
                                    appraiseTiesId = null;
                                    break;
                            }
                            if (appraiseTiesId == null) {
                                list.get(i).get(i + 1).put(list.get(i).get(i + 1).size() - 1, "5");
                                break;
                            }
                        }
                    }
                }
            }

            Map<Integer, String> content = list.get(i).get(i + 1);
            if (content.get(list.get(i).get(i + 1).size() - 1).equals("0")) {//正常的数据入库
                Appraise appraise = new Appraise();
                appraise.setDeptId(String.valueOf(byMobile.getDeptId()));
                appraise.setDeptName(byMobile.getDeptName());
                appraise.setAppraiserId(String.valueOf(byMobile.getMobile()));
                appraise.setAppraiserName(byMobile.getRealName());
                appraise.setAppraiserPhone(byMobile.getMobile());
                appraise.setAssessedId(String.valueOf(byRealName.getMobile()));
                appraise.setAssessedName(byRealName.getRealName());
                appraise.setAssessedDept(byRealName.getDeptName());
                appraise.setAppraiseTiesId(appraiseTiesId);
                appraise.setAppraiseTies(content.get(6));
                appraise.setQuestionId(questionId);
                appraiseMapper.insertAppraise(appraise);
                successCount++;
            }
            resultList.add(list.get(i).get(i + 1));
        }
        resultMap.put("sum", list.size());
        resultMap.put("success", successCount);
        resultMap.put("fail", list.size() - successCount);
        resultMap.put("detail", resultList);
        return resultMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertAppraise(AppraiseDto appraiseDto) {
        Appraise appraise = new Appraise();

        for (AppraiseDto.subList list : appraiseDto.getSubList()) {
            BeanUtils.copyProperties(appraiseDto, appraise);
            appraise.setAssessedId(list.getAssessedId());
            appraise.setAssessedName(list.getAssessedName());
            appraise.setAssessedDept(list.getAssessedDept());
            appraise.setAppraiseTiesId(list.getAppraiseTiesId());
            appraise.setAppraiseTies(list.getAppraiseTies());
            appraiseMapper.insertAppraise(appraise);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAppraise(AppraiseDto appraiseDto) {
        Appraise appraise = new Appraise();

        Map<String, Object> map = new HashMap<>();
        map.put("questionIdList", Arrays.asList(appraiseDto.getQuestionId()));
        map.put("appraiserIdList", Arrays.asList(appraiseDto.getAppraiserId()));

        appraiseMapper.deleteAppraise(map);

        for (AppraiseDto.subList list : appraiseDto.getSubList()) {
            BeanUtils.copyProperties(appraiseDto, appraise);
            appraise.setAssessedId(list.getAssessedId());
            appraise.setAssessedName(list.getAssessedName());
            appraise.setAssessedDept(list.getAssessedDept());
            appraise.setAppraiseTiesId(list.getAppraiseTiesId());
            appraise.setAppraiseTies(list.getAppraiseTies());
            appraiseMapper.insertAppraise(appraise);
        }

    }

    @Override
    public PageData<Appraise> getAppraiseShow(Appraise appraise) {
        appraise.setPage2((appraise.getPage2() - 1) * appraise.getLimit2());
        Integer count = appraiseMapper.getAppraiseShowCount(appraise.getQuestionId(), appraise.getAppraiserPhone());
        List<Appraise> appraisesList = appraiseMapper.getAppraiseList(appraise);
        for (int i = 0; i < appraisesList.size(); i++) {
            Appraise value = appraisesList.get(i);
            List<Appraise> appraiseTimeList = appraiseMapper.getScoreList(value.getAppraiserId(), value.getAssessedName(), value.getQuestionId());
            if (appraiseTimeList.size() == 0) {
                value.setAppraiseStatus(0);
                value.setAppraiseTime(null);
            } else {
                value.setAppraiseStatus(1);
                value.setAppraiseTime(appraiseTimeList.get(appraiseTimeList.size() - 1).getAppraiseTime());
            }
            if (appraise.getAppraiseStatus() != null) {
                if (!value.getAppraiseStatus().equals(appraise.getAppraiseStatus())) {
                    appraisesList.remove(value);
                    i--;
                }
            }
        }
        return new PageData<>(appraisesList, count);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAppraise(Map<String, Object> map) {
        List appraiserIdList = (List) map.get("appraiserIdList");
        map.put("userIdList", appraiserIdList);

        scoreMapper.deleteScoring(map);
        appraiseMapper.deleteAppraise(map);
    }

    @Override public AppraiseDetail getAppraiseDetail(String appraiserPhone, String assessedId, String questionId) { AppraiseDetail appraiseDetail = appraiseMapper.getAppraiseDetail(appraiserPhone, assessedId, questionId); List<AppraiseDetail.AssessList> assessList = appraiseDetail.getAssessList(); String[] scoreSplit = new String[]{};
        if (appraiseDetail.getUserScore() != null) {
            scoreSplit = appraiseDetail.getUserScore().split(",");
        }

        for (int i = 0; i < assessList.size(); i++) {
            List<String> scoreList = Arrays.asList(assessList.get(i).getAssessScore().split(","));
            List<String> itemList = Arrays.asList(assessList.get(i).getAssessItem().split(","));
            int isRating = assessList.get(i).getIsRating();

            int indexOf = -1;
            if (scoreSplit.length > 0 && scoreSplit.length > i) {
                if (isRating == 2) {
                    scoreList = itemList; // 处理isRating为2的情况
                }
                indexOf = scoreList.indexOf(scoreSplit[i]);
            }

            if (indexOf != -1) {
                assessList.get(i).setScoreKey(scoreList.get(indexOf));
                assessList.get(i).setScoreValue(itemList.get(indexOf));
            } else {
                assessList.get(i).setScoreKey("");
                assessList.get(i).setScoreValue("");
            }
        }

        return appraiseDetail;}
    @Override
    public R<String> sendAnswerMessage(String questionId, List appraiserPhoneList) {

        Map<String, Object> map = new HashMap<>();
        map.put("mobileList", appraiserPhoneList);

        List<SysUserEntity> list = sysUserDao.getList(map);

        for (SysUserEntity sysUserEntity : list) {
            String code = "0";
            String sendTSMS = null;
            // 发送验证码
            if (!"dev".equals(propertiesConfig.getEnv())) {
                String password = null;
                try {
                    password = new String(Base64.getDecoder().decode(sysUserEntity.getPassword2()), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                sendTSMS = smsSend.sendTSMS(sysUserEntity.getMobile(), sysUserEntity.getUsername(), password);
                JSONObject jsonObject = JSONObject.parseObject(sendTSMS);
                code = jsonObject.get("code").toString();
            }

            if (!"0".equals(code)) {
                log.info("短信发送能力调用失败，错误信息为:{}", sendTSMS);
                return R.failed("短信发送能力调用失败");
            } else {
                Appraise appraise = new Appraise();
                appraise.setAppraiserId(sysUserEntity.getMobile());
                appraise.setQuestionId(questionId);
                appraise.setAppraiseNotice(1);
                appraiseMapper.updateAppraise(appraise);
            }
        }

        return R.success("短信发送成功");
    }

    @Transactional
    @Override
    public AnalyseOwnVo getEvaluateObjects(Appraise appraise) {
        AnalyseOwnVo evaluateObject = appraiseMapper.getEvaluateObjects(appraise);
        for (AnalyseOwnVo.AppraiserUser appraiserUser : evaluateObject.getAppraiserUser()) {
            appraiserUser.setAppraiseStatus(1);
        }
        List<AnalyseOwnVo.AppraiserUser> filteredAppraiserUsers = evaluateObject.getAppraiserUser().stream()
                .filter(user -> user.getAppraiseStatus() == 1)
                .collect(Collectors.toList());

        ScoreDto scoreDto = new ScoreDto();
        scoreDto.setQuestionId(appraise.getQuestionId());
        List<AnalyseListVo> analyseList = scoreImpl.getAnalyseListss(scoreDto, appraise.getQuestionId());
        for (AnalyseListVo analyseItem : analyseList) {
            for (AnalyseOwnVo.AppraiserUser appraiserUser : filteredAppraiserUsers) {
                if (analyseItem.getAssessedId().equals(appraiserUser.getAssessedId())) {
                    appraiserUser.setQuanzhong(analyseItem.getQuanzhong());
                    break;
                }
            }
        }
         return evaluateObject;
    }

    @Override
    public void deleteQuestionId(String questionId) {
        appraiseMapper.deleteQuestionId(questionId);
    }

    @Override
    public List<Fraction> getfraction() {
        return appraiseMapper.getfraction();
    }


}
